<?php


namespace App\Repositories;


use Exception;
use LTools\Repositories\RepositoryAbstract;

class BatchInventory extends RepositoryAbstract
{
    /**
     * BatchInventory constructor.
     * @param \App\Models\BatchInventory $model
     * @author luffyzhao@vip.126.com
     */
    public function __construct(\App\Models\BatchInventory $model)
    {
        $this->model = $model;
    }

    /**
     * @param int $productId
     * @param int $quantity 数量
     * @param int $attribute 是否用不良品
     * @param int $expire
     * @param int $expiry 是否用过期产品
     * @return array
     * @throws \Throwable
     * @author luffyzhao@vip.126.com
     */
    public function productDecrement($productId, int $quantity, $attribute = 0, $expire = 0, $expiry = null)
    {
        $newQuery = $this->model->newQuery()
            ->where('product_id', '=', $productId)
            ->where('attribute', '=', $attribute)
            ->where('expire', '=', $expire)
            ->orderBy('expiry')
            ->orderBy('warehousing_id');
        if ($expiry !== null) {
            $newQuery->where('expiry', '>', $expiry);
        }
        $batches = $newQuery->get();

        $batchArray = [];
        foreach ($batches as $batch) {
            $batch = $this->model->newQuery()->where('id', '=', $batch->getKey())->lockForUpdate()->first();
            if ($batch->getAttribute('quantity') >= $quantity) {
                // 记录
                $batchArray[] = [
                    'batch_inventory_id' => $batch->getKey(),
                    'barcode' => $batch->getAttribute('barcode'),
                    'product_id' => $batch->getAttribute('product_id'),
                    'quantity' => $quantity,
                ];
                // 没库存时软删除
                if ($batch->getAttribute('quantity') === $quantity) {
                    // 货架产品数据减一
                    $batch->location()->decrement('count');

                    $batch->setAttribute('deleted_at', $batch->fromDateTime($batch->freshTimestamp()));
                }
                $batch->setAttribute('quantity', $batch->getAttribute('quantity') - $quantity);
                $batch->saveOrFail();
                $quantity = 0;
                break;
            }
            // 批次不够用时
            if ($batch->getAttribute('quantity') < $quantity) {
                // 记录
                $batchArray[] = [
                    'batch_inventory_id' => $batch->getKey(),
                    'barcode' => $batch->getAttribute('barcode'),
                    'product_id' => $batch->getAttribute('product_id'),
                    'quantity' => $batch->getAttribute('quantity'),
                ];
                // 货架产品数据减一
                $batch->location()->decrement('count');
                // 减该减的
                $quantity -= $batch->getAttribute('quantity');
                // 没库存时软删除
                $batch->setAttribute('deleted_at', $batch->fromDateTime($batch->freshTimestamp()));
                $batch->setAttribute('quantity', 0);
                $batch->saveOrFail();
            }
        }

        if ($quantity > 0) {
            throw new Exception("产品[%s]库存不足");
        }

        return $batchArray;
    }
}
